using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using UCS.XNA.Utils;
using Hopeless.Physical;
using Hopeless.Metaphysical.GUI;

namespace Hopeless.Metaphysical
{
    public class HopelessGame : Game
    {
        #region Constants

        public const string TITLE = "Hopeless";

        #endregion

        #region Private Fields

        private GraphicsDeviceManager _graphics;
        private SpriteBatch _spriteBatch;
        private GameState _gameState;
        private Player _player;
        private MainMenuWindow _mainMenu;
        private WaveCompletedWindow _waveCompletedWindow;
        private Rectangle _screenSpace;
        private HUD _hud;

        #endregion

        #region Attributes and Properties

        private static Universe _universe;
        public static Universe Universe
        {
            get { return _universe; }
        }

        private bool _paused = false;
        public bool Paused
        {
            get { return _paused; }
            set { _paused = value; }
        }

        #endregion

        #region Constructors

        public HopelessGame()
        {
            _graphics = new GraphicsDeviceManager(this);
            this.Content.RootDirectory = "Content";
            _graphics.PreferredBackBufferWidth = 800;
            _graphics.PreferredBackBufferHeight = 600;
            this.IsMouseVisible = true;
            _universe = new Universe();
            _player = new Player(this);
            _mainMenu = new MainMenuWindow(this);
        }

        #endregion

        #region Overriden Methods

        protected override void Initialize()
        {
            base.Initialize();
            GameResources.Graphics = _graphics;
            GameResources.SpriteBatch = _spriteBatch;
            GameResources.Content = this.Content;

            _gameState = GameState.MainMenu;

            _screenSpace = new Rectangle(0, 0, _graphics.PreferredBackBufferWidth, _graphics.PreferredBackBufferHeight);
            _mainMenu.Initialize(_screenSpace);

            _hud = new HUD(this);
            _hud.Initialize(_screenSpace);
        }

        protected override void LoadContent()
        {
            _spriteBatch = new SpriteBatch(GraphicsDevice);
        }

        protected override void UnloadContent()
        {
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            base.Update(gameTime);

            if (_gameState == GameState.InGame)
            {
                if (_waveCompletedWindow == null)
                {
                    _player.Update(gameTime);

                    if (_paused)
                        return;

                    _universe.Update(gameTime);
                    Physics.Update(gameTime);

                    if (_universe.CurrentWaveFinished && !_universe.AllWavesFinished)
                    {
                        _waveCompletedWindow = new WaveCompletedWindow();
                        var width = _screenSpace.Width * 0.7f;
                        var height = _screenSpace.Height * 0.7f;
                        var x = _screenSpace.Width / 2f - width / 2f;
                        var y = _screenSpace.Height / 2f - height / 2f;
                        var space = new Rectangle((int)x, (int)y, (int)width, (int)height);
                        _waveCompletedWindow.Initialize(space);
                    }
                }
                else
                {
                    _waveCompletedWindow.Update(gameTime);
                    if (_waveCompletedWindow.NextWaveRequested)
                    {
                        _waveCompletedWindow = null;
                        _universe.StartNextWave();
                    }
                }
            }
            else
                _mainMenu.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            if (_gameState == GameState.InGame)
            {
                _universe.Draw(gameTime);
                _hud.Draw(gameTime);

                if (_waveCompletedWindow != null)
                    _waveCompletedWindow.Draw(gameTime);
            }
            else
                _mainMenu.Draw(gameTime);

            base.Draw(gameTime);
        }

        public void Start()
        {
            var screenSpace = new Rectangle(0, 0, _graphics.PreferredBackBufferWidth, _graphics.PreferredBackBufferHeight);
            _universe.Initialize(screenSpace);

            _gameState = GameState.InGame;
        }

        public void OpenMainMenu()
        {
            _mainMenu.Initialize(_screenSpace);
            _gameState = GameState.MainMenu;
        }

        #endregion
    }
}
